#include "editor/gui/tilesview.hpp"       

#include "resourcehandler.hpp"
#include "guichan/allegro.hpp"

namespace nmc
{
    TilesView::TilesView()
        : mSelectedTile(0),
          mDrawMouseHoverTile(false),
          mFrameCounter(0)
    {
        mTileSetBitmap = ResourceHandler::getInstance()->getBitmap("tileset.bmp");
        setWidth(mTileSetBitmap->w);
        setHeight(mTileSetBitmap->h);

        addMouseListener(this);
    }

    void TilesView::draw(gcn::Graphics* graphics)
    {
        gcn::AllegroGraphics* allegroGraphics = static_cast<gcn::AllegroGraphics*>(graphics);

        allegroGraphics->drawBitmap(mTileSetBitmap, 0, 0);

        int selectedX = (mSelectedTile % (mTileSetBitmap->w / 16)) * 16;
        int selectedY = (mSelectedTile / (mTileSetBitmap->w / 16)) * 16;
        graphics->pushClipArea(gcn::Rectangle((mSelectedTile % (mTileSetBitmap->w / 16)) * 16,
                                              (mSelectedTile / (mTileSetBitmap->w / 16)) * 16,
                                              16,
                                              16));
                                             
        drawSelectedTileMarker(graphics);
        graphics->popClipArea();

        if (mDrawMouseHoverTile)
        {
            graphics->setColor(gcn::Color(0x0000ff));
            graphics->drawRectangle(gcn::Rectangle(mCurrentMouseX - mCurrentMouseX % 16,
                                                   mCurrentMouseY - mCurrentMouseY % 16,
                                                   16,
                                                   16));
        }
    }

    void TilesView::drawSelectedTileMarker(gcn::Graphics* graphics)
    {   
        int pixelsDrawn;
        
        if (mFrameCounter % 40 < 10)
        {
            pixelsDrawn = 0;   
        }
        else if (mFrameCounter % 40 < 20)
        {
            pixelsDrawn = 1;
        }
        else if (mFrameCounter % 40 < 30)
        {
            pixelsDrawn = 2;
        }
        else
        {
            pixelsDrawn = 3;
        }

        int x;
        for (x = 0; x < 16; x++)
        {
            if (pixelsDrawn % 4 < 2)
            {
                graphics->setColor(gcn::Color(0x000000));
            }
            else
            {
                graphics->setColor(gcn::Color(0xffffff));
            }

            graphics->drawPoint(x, 0);
            graphics->drawPoint(x, 15);
            pixelsDrawn++;
        }

        int y;
        for (y = 0; y < 16; y++)
        {
            if (pixelsDrawn % 4 < 2)
            {
                graphics->setColor(gcn::Color(0x000000));
            }
            else
            {
                graphics->setColor(gcn::Color(0xffffff));
            }

            graphics->drawPoint(0, y);
            graphics->drawPoint(15, y);
            pixelsDrawn++;
        }
    }

    void TilesView::logic()
    {
        mFrameCounter++;
    }

    void TilesView::mouseMoved(gcn::MouseEvent& mouseEvent)
    {
        if (mouseEvent.getX() <= mTileSetBitmap->w
            && mouseEvent.getY() <= mTileSetBitmap->h)
        {
            mCurrentMouseX = mouseEvent.getX();
            mCurrentMouseY = mouseEvent.getY();
            mDrawMouseHoverTile = true;
        }
        else
        {
            mDrawMouseHoverTile = false;
        }
    }

    void TilesView::mouseEntered(gcn::MouseEvent& mouseEvent)
    {
        mDrawMouseHoverTile = true;
    }

    void TilesView::mouseExited(gcn::MouseEvent& mouseEvent)
    {
        mDrawMouseHoverTile = false;
    }

    void TilesView::mousePressed(gcn::MouseEvent& mouseEvent)
    {
       if (mouseEvent.getX() <= mTileSetBitmap->w
            && mouseEvent.getY() <= mTileSetBitmap->h)
        {
            mSelectedTile = mouseEvent.getX() / 16
                          + (mouseEvent.getY() / 16) * mTileSetBitmap->w / 16;
            generateAction();
        }
    }

    int TilesView::getSelectedTile()
    {
        return mSelectedTile;
    }

    void TilesView::setSelectedTile(int selectedTile)
    {
        mSelectedTile = selectedTile;
    }
}